// ValidationAspects
// Written by Mike Saunders
// Released under Microsoft Public License (Ms-PL)
using System;
using System.Linq;
using System.Reflection;
using PostSharp.Laos;
using ValidationAspects.Core;
using ValidationAspects.Sdk;
using ValidationAspects.Sdk.Interception;

namespace ValidationAspects.PostSharp
{
	[Serializable]
	public class PropertyValidationAspect : OnMethodBoundaryAspect
	{
		private readonly string _propertyName;

		[NonSerialized]
		private PropertyInfo _propertyInfo;

		public PropertyValidationAspect(string propertyName)
		{
			Enforce.IsNotNullOrEmpty(propertyName, "propertyName");
			_propertyName = propertyName;
		}

		public override void OnEntry(MethodExecutionEventArgs eventArgs)
		{
			// discover the PropertyInfo. Do this here instead of within RuntimeInitialize(...) as this may be applied to a generic type
			if (_propertyInfo == null)
				_propertyInfo = eventArgs.Method.DeclaringType.GetAllProperties().First(pi => pi.Name == _propertyName);

			InterceptValidate.Property(_propertyInfo, eventArgs.Instance, eventArgs.GetReadOnlyArgumentArray()[0]);
		}
	}
}